<template>
  <div>
    <a-card style="margin-bottom: 10px" :style="`width:` + width" v-for="(item, index) in thatState" :key="item.key">
      <div class="my-card-group">
        <a-form-item-rest>
          <slot :data="item || {}"></slot>
        </a-form-item-rest>
        <div class="my-delete-card-group" v-if="thatState.length > minCardNumber && showDelete">
          <Popconfirm :title="deleteTitle" @confirm="handleDeleteCardGroup(index)">
            <Button danger>
              <template #icon>
                <Icon icon="i-ant-design:delete-twotone" class="my-card-group-delete-icon" :size="16" />
              </template>
            </Button>
          </Popconfirm>
        </div>
      </div>
    </a-card>
    <div :style="`width:` + width" class="my-add-card-group">
      <Button type="dashed" v-if="showAddCardButton" style="width: 100%" @click="handleAddCard">{{ addCardButtonName }}</Button>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { watch, ref, unref, PropType, onMounted, watchEffect, nextTick } from "vue"
  import { Button, Popconfirm } from "ant-design-vue"
  import { propTypes } from "/@/utils/propTypes"
  import { Icon } from "/@/components/Icon"
  import { useAttrs } from "/@/hooks/core/useAttrs"
  import { isArray } from "lodash-es"

  const thatState = ref<any[]>([])
  const attrs = useAttrs()
  const keys = ref<Map<any, string>>(new Map())
  const preData = ref()
  const props = defineProps({
    value: propTypes.array.def([]),
    width: propTypes.string.def("100%"),
    deleteTitle: propTypes.string.def("确定删除吗？"),
    showDelete: propTypes.bool.def(true),
    addCardButtonName: propTypes.string.def("添加数据"),
    showAddCardButton: propTypes.bool.def(true),
    // 添加卡片时候的默认数据
    defaultData: propTypes.object.def({}),
    // 是否初始化一条数据
    isInitOne: propTypes.bool.def(true),
    // 最小卡片数, 如果值小于这个数量, 则不展示删除
    minCardNumber: propTypes.number.def(1),
    beforeAdd: {
      type: Function,
      default: (...arg: any) => true,
    },
    beforeDelete: {
      type: Function,
      default: (...arg: any) => true,
    },
  })
  const emit = defineEmits(["change", "update:value", "remove"])
  onMounted(() => {
    if (props.isInitOne) {
      handleAddCard()
    }
  })

  watch(
    () => thatState.value,
    (data) => {
      if (JSON.stringify(data) !== JSON.stringify(preData.value)) {
        preData.value = data
        emitValue()
      }
    },
    { deep: true }
  )

  watchEffect(() => {
    if (props.value) {
      const value: any[] = props.value
      if (value.length > 0) {
        thatState.value = value.map((e) => {
          const key = e.key ? e.key : new Date().getTime()
          return { ...e, key }
        })
      }
      value.length === 0 &&
        nextTick(() => {
          emitValue()
        })
    } else {
      nextTick(() => {
        emitValue()
      })
    }
  })

  const handleChange = (values) => {
    emitValue()
  }

  const handleDeleteCardGroup = (index) => {
    const record = thatState.value[index]
    console.log("will deleted record: ", record)
    if (!props.beforeDelete(record)) {
      return
    }
    emit("remove", record)
    thatState.value.splice(index, 1)
    emitValue()
  }

  const handleAddCard = () => {
    const ret = props.beforeAdd()
    if (ret) {
      thatState.value.push({ ...props.defaultData, key: new Date().getTime() })
      emitValue()
    }
  }

  const emitValue = () => {
    if (thatState.value.length === 0) {
      return
    }
    const value = unref(thatState)
    emit("change", value)
    emit("update:value", value)
  }
</script>

<style lang="less">
  .my-card-group {
    display: flex;
    flex-flow: column;
    // margin-bottom: -5px;
    margin-top: -10px;
  }

  .my-add-card-group {
    margin-top: 10px;
  }

  .my-delete-card-group {
    position: absolute;
    right: -40px;
    top: 0px;
    .ant-btn {
      width: 32px;
      height: 32px;
    }
  }

  .my-card-group-delete-icon {
    padding: 0px;
  }
</style>
